

macro DllStub()
{
//	strFile="WWANNDIS\\wwan.h"
//	if(hNil==hbuf){
//		Msg("No such file @strFile@")
//		return
//	}

//	hbuf=GetBufHandle (strFile)

	hbufSymbl=GetCurrentBuf ()
	hbufTypedef=NewBuf("dllstub.c")
	hbufDllMain=NewBuf("")
	hbufImplete=NewBuf("")
	
	cntSymb=GetBufSymCount(hbufSymbl)
	i=0
	while(i<cntSymb){
		symbl=GetBufSymLocation(hbufSymbl, i)
		if("Function Prototype"==symbl.Type){
//Msg(symbl)
			AppendTypedef(hbufTypedef, hbufSymbl, symbl)
			AppendDllMain(hbufDllMain, symbl)
			AppendImpletment(hbufImplete, hbufSymbl, symbl)
		}
		i=i+1
	}

	// append dllmain
	AppendBufLine(hbufTypedef, "")
	AppendBufLine(hbufTypedef, "BOOL WINAPI DllMain(HANDLE hinstDll, DWORD dwReason, LPVOID lpReserved )")
	AppendBufLine(hbufTypedef, "{")
	AppendBufLine(hbufTypedef, "    static HMODULE l_hDLLOrg;")
	AppendBufLine(hbufTypedef, "    if (DLL_PROCESS_ATTACH == dwReason){")
	AppendBufLine(hbufTypedef, "        l_hDLLOrg = (HMODULE) LoadLibrary(TEXT(\"XXX_Org.dll\"));")
	AppendBufLine(hbufTypedef, "        if(NULL==l_hDLLOrg){return FALSE;}")
	AppendBufLine(hbufTypedef, "")
	InsBuf2Buf(hbufTypedef, "-1", hbufDllMain, 0, "-1")
	AppendBufLine(hbufTypedef, "    }else{")
	AppendBufLine(hbufTypedef, "        FreeLibrary(l_hDLLOrg);")
	AppendBufLine(hbufTypedef, "    }")
	AppendBufLine(hbufTypedef, "    return TRUE;")
	AppendBufLine(hbufTypedef, "}")

	// append function implement
	AppendBufLine(hbufTypedef, "")
	InsBuf2Buf(hbufTypedef,"-1", hbufImplete, 0, "-1")

	CloseBuf(hbufDllMain)
	CloseBuf(hbufImplete)

	hwnd=NewWnd (hbufTypedef)
	MaximizeWnd (hwnd)
}


macro AppendTypedef(hbuf, hbufSymb, symb)
{
	AppendBufLine(hbuf, "typedef")
	
	// append declare
	lnAfterAppend=InsBuf2Buf(hbuf, "-1", hbufSymb, symb.lnFirst, symb.lnLim)

	Symbol=symb.Symbol
	
	// replace to function define
	ReplaceInBuf(hbuf, Symbol, "(*pfn_@Symbol@)", lnAfterAppend-symb.lnLim, lnAfterAppend, 1, 0, 1, 0)

	// add function variable  declare
	AppendBufLine(hbuf, "pfn_@Symbol@ g_pfn_@Symbol@=NULL;")

	// add empty line
	AppendBufLine(hbuf, "")
	
}

macro AppendDllMain(hbuf, symb)
{
	Symbol=symb.Symbol
	s="        g_pfn_@Symbol@=(pfn_@Symbol@)GetProcAddress(l_hDLLOrg, TEXT(\"@Symbol@\"));"
	AppendBufLine(hBuf, s)
}

macro AppendImpletment(hbuf, hbufSymb, symb)
{
	Symbol=symb.Symbol
	
	// append declare
	lnAfterAppend=InsBuf2Buf(hbuf, "-1", hbufSymb, symb.lnFirst, symb.lnLim)
	ReplaceInBuf(hbuf, ";", "", lnAfterAppend-1, lnAfterAppend, 1, 0, 1, 0)
	AppendBufLine(hbuf, "{")
	AppendBufLine(hbuf, "	FUNTRACE(@Symbol@, (), ());")
	AppendBufLine(hbuf, "	return g_pfn_@Symbol@(")
	AppendFunPara(hbuf, symb)
	AppendBufLine(hbuf, "    );")
	AppendBufLine(hbuf, "}")
	AppendBufLine(hbuf, "")
}


macro AppendFunPara(hbuf, symblFun)
{
	//
	// get paras
	hsymlChld = SymbolChildren(symblFun)
	cntChld = SymListCount(hsymlChld)
	
	hbufPara=NewBuf("")
	cntPara=0
	i = 0
	while (i < cntChld){
		synblChld = SymListItem(hsymlChld, i)
		if("Parameter"==synblChld.Type){
			InsAndSortParaBuf(hbufPara, synblChld)
			cntPara=cntPara+1
		}
		i=i+1
	}
	SymListFree(hsymlChld)

	iFunNameLen=strlen(symblFun.Symbol)
	iFunNameLen=iFunNameLen+1
	i=0
	while (i < cntPara){
		synblPara=GetBufLine(hbufPara, i)
		iParaLen=strlen(synblPara.Symbol)
		Symbol=strmid(synblPara.Symbol, iFunNameLen, iParaLen)
		i=i+1
		if(cntPara!=i){
			s="        @Symbol@,"
		}else{
			s="        @Symbol@"
		}
		AppendBufLine(hbuf, s)
	}	

	CloseBuf(hbufPara)
}


// insert symbol:symblPara to special buf line according to the symblPara's location (line and column)
macro InsAndSortParaBuf(hParaBuf, symblPara)
{
	cntBufLn=GetBufLineCount(hParaBuf)
	
	i=0
	while(i<cntBufLn){
		symblCur=GetBufLine(hParaBuf, i)
		if(symblPara.lnName<symblCur.lnName){
//Msg("InsBufLine @i@")
			InsBufLine(hParaBuf, i, symblPara)
			return
		}
		if(symblPara.lnName==symblCur.lnName){
			if(symblPara.ichName<symblCur.ichName){
//Msg("InsBufLine @i@")
				InsBufLine(hParaBuf, i, symblPara)
				return
			}
		}
		
		i=i+1
	}
	
//Msg("AppendBufLine")
	AppendBufLine(hParaBuf, symblPara)
}


